using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(CharacterKeyFrame))]  
public class CharacterKeyFrameInspector : Editor
{
	private CharacterKeyFrame frame;
	private Character character;
	private CharacterAnimatedState state;
	
	private CharacterAction[] actions = null;
	private int currentFrame;
	private bool refreshActions = true;
	private bool[] showActions = null;
	private Editor[] actionEditors = null;
	
	
	public override void OnInspectorGUI () 
	{  
		frame = target as CharacterKeyFrame;
		state = frame.transform.parent.GetComponent<CharacterAnimatedState>();
		if(state == null)
		{
			EditorGUILayout.LabelField("State Invalid"); 
			return;
		}
		character = state.transform.parent.parent.GetComponent<Character>();
		if(character == null)
		{
			EditorGUILayout.LabelField("Character Invalid"); 
			return;
		}
		character.IndexStates();
		state.InitFramesInfo();
		frame.DisplayFrame();
		actions = frame.GetComponentsInChildren<CharacterAction>();
		if(currentFrame < frame.start)
			currentFrame = frame.start;
		else if(frame.start >= frame.end)
			frame.start = frame.end - 1;
		CustomAnimationSampler.CustomSampleAnimation(character, state.animationClip, currentFrame);
		
		DrawFrameInfo();
		DrawAddAction();
		DrawActions();
	} 
	
	void DrawAddAction()
	{
		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField(string.Format("{0} Action(s) Attached", actions.Length));
		if(GUILayout.Button("Add Action", GUILayout.MaxWidth(150)))
		{
			GenericMenu menu  = new GenericMenu ();
			string name = "Character/Add Frame Action/0 Create Object";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/1 Play Sound";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/2 AddDefenseShell";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);

            name = "Character/Add Frame Action/3 DieDown";
            menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);

            name = "Character/Add Frame Action/4 ActivateFlashEffect";
            menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);

            name = "Character/Add Frame Action/5 ChangePhysicsConstraintsEffect";
            menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);

            name = "Character/Add Frame Action/6 CounterTriggerEffect";
            menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/7 AddCameraEffect";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/8 AddTimeScaleEffect";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/9 Set Target Rotation On Direction";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/10 Turn To Target Rotation On Update";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/11 Move On Direction";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/12 Move By Speed On Update";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/13 Move By Curve On Update";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/14 Position By Curve On Update";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/15 Position By Value On Update";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/16 Position By Value Group On Update";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/17 Injury";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/18 AnimateTiledTexture";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/Transition/19 Transition On Button";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/Transition/20 Transition On Direction";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			name = "Character/Add Frame Action/Transition/21 Emit Pocket RPG weapon Trail";
			menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);

            name = "Character/Add Frame Action/Transition/22 SlashAction";
            menu.AddItem (new GUIContent (name), false, AddActionContextCallback, name);
			
			menu.ShowAsContext ();
		}
		if(GUILayout.Button("Save Curve", GUILayout.MaxWidth(150)))
		{
			SaveCurvesAction();
		}
		if(GUILayout.Button("Load Curve", GUILayout.MaxWidth(150)))
		{
			LoadCurvesAction();
		}
		EditorGUILayout.EndHorizontal();
	}
	
	void SaveCurvesAction()
	{
		foreach(CharacterAction action in actions)
		{
			if(action is MoveByCurveOnUpdate)
			{
				MoveByCurveOnUpdate curveAction = action as MoveByCurveOnUpdate;
				MoveByCurveInspector inspector = (MoveByCurveInspector)(Editor.CreateEditor(curveAction));
				inspector.SaveAllCurves(curveAction);
			}
			
			if(action is PositionByCurveOnUpdate)
			{
				PositionByCurveOnUpdate curveAction = action as PositionByCurveOnUpdate;
				PositionByCurveInspector inspector = (PositionByCurveInspector)(Editor.CreateEditor(curveAction));
				inspector.SaveAllCurves(curveAction);
			}
		}
	}
	
	void LoadCurvesAction()
	{
		foreach(CharacterAction action in actions)
		{
			if(action.name.Contains("Curve"))
			{
				MoveByCurveOnUpdate curveAction = action as MoveByCurveOnUpdate;
				MoveByCurveInspector inspector = (MoveByCurveInspector)(Editor.CreateEditor(curveAction));
				inspector.LoadAllCurves(curveAction);
			}
			
			if(action is PositionByValueOnUpdate)
			{
				PositionByCurveOnUpdate curveAction = action as PositionByCurveOnUpdate;
				PositionByCurveInspector inspector = (PositionByCurveInspector)(Editor.CreateEditor(curveAction));
				inspector.SaveAllCurves(curveAction);
			}
		}
	}
	
	void AddActionContextCallback(object name)
	{
		EditorApplication.ExecuteMenuItem(name.ToString());
		EditorUtility.SetDirty(frame.gameObject);
		refreshActions = true;
	}
	
	void DrawFrameInfo()
	{
		//frame.always = EditorGUILayout.Toggle("Always", frame.always);
		if(frame.always)
		{
			currentFrame = EditorGUILayout.IntSlider("Current Frame", currentFrame, 0, state.frames - 1);
			serializedObject.ApplyModifiedProperties(); 
		}
		else
		{
			float start = frame.start;
			float end = frame.end;
			
			EditorGUILayout.BeginHorizontal();
			start = EditorGUILayout.IntField((int)start, GUILayout.MaxWidth(40));
			EditorGUILayout.MinMaxSlider(ref start, ref end, 0f, (float)state.frames);				
			end = EditorGUILayout.IntField((int)end, GUILayout.MaxWidth(40));
			EditorGUILayout.EndHorizontal();
			
			frame.start = (int)start;
			frame.end = (int)end;
			frame.duration = (frame.start + 1 < frame.end);
			
			currentFrame = EditorGUILayout.IntSlider("Current Frame", currentFrame, frame.start, frame.end - 1);
			
			serializedObject.ApplyModifiedProperties(); 
			if(frame.end <= frame.start)
				frame.end = frame.start+1;
		}
	}
	
	void DrawActions()
	{
		if(refreshActions)
		{
			RefreshActionInspector();
		}
		for(int i = 0; i < actions.Length; i++)
		{ 
			showActions[i] = EditorGUILayout.InspectorTitlebar(showActions[i], actions[i]);
			if(showActions[i])
			{
				actionEditors[i].OnInspectorGUI();
			}
		} 
	}
	
	void RefreshActionInspector()
	{
		if(frame == null)
		{
			actionEditors = null;
			showActions = null;
			return;
		}
		
		showActions = new bool[actions.Length];
		actionEditors = new Editor[actions.Length];
		for(int i = 0; i < actions.Length; i++)
			actionEditors[i] = CreateEditor(actions[i]);
		
		refreshActions = false;
	}
	
	void RefreshCharacterAnimation()
	{
		
	}
}

